package iceberg;

import iceberg.domain.Layer;
import iceberg.domain.Unit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class LayerCache {

	private static final Logger LOG = LoggerFactory.getLogger(LayerCache.class);

	private final Map<Unit, Layer> cache = new HashMap<Unit, Layer>();
	private Set<Layer> layers;

	public void setLayers(Set<Layer> layers) {
		this.layers = layers;
	}

	public LayerCache() {
	}


	public Layer getLayerForUnit(Unit unit) {
		Layer layer = cache.get(unit);
		if (layer == null) {
			LOG.info("Cache mis " + unit.getName());
			layer = findLayer(unit);
			if (layer != null) {
				cache.put(unit, layer);
				LOG.info("Cache insertion");
			}
		} else {
			LOG.info("Cache hit " + unit.getName());
		}

		return layer;
	}

	private Layer findLayer(final Unit unit) {
		Layer result = searchLayers(unit);
		if (result != null) {
			LOG.info("Found on initial try");
			return result;
		}

		Unit tempUnit = unit;
		while (tempUnit.hasParent()) {
			tempUnit = tempUnit.getParent();
			LOG.info("Trying parent " + tempUnit);
			result = findLayer(tempUnit);
			if (result != null) {
				LOG.info("Found in parent " + tempUnit );
				return result;
			}

		}

		return null;
	}

	private Layer searchLayers(Unit unit) {
		for (Layer layer : layers) {
			if (layer.contains(unit)) {
				return layer;
			}
		}
		return null;
	}
}
